#pragma once
#include "TextInputDlg.h"
#include "SkinnedInt.h"

class CIntInputDlg : public CTextInputDlg
{
public:

  void SetRange(int min, int max)
  { m_slider.SetRange(min, max); }

	BEGIN_MSG_MAP(CTextInputDlg)
    MESSAGE_HANDLER(WM_CREATE, OnCreate)
    MESSAGE_HANDLER(WM_SIZE, OnSize)

    MESSAGE_HANDLER(WM_INTVALUECHANGED, OnIntChanged)
    COMMAND_CODE_HANDLER_EX(EN_CHANGE, OnEditChanged)

    MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnColorEdit)

    MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown)

    CHAIN_MSG_MAP(CTextInputDlg)
  END_MSG_MAP()

  LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
  {
    CString s;
    GetWindowText(s);
    m_header.Create(m_hWnd, NULL, s, WS_CHILD | WS_VISIBLE);
    m_slider.Create(m_hWnd, NULL, NULL, WS_CHILD | WS_VISIBLE);
    return bHandled = FALSE;
  }

  LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  {
    if (wParam != SIZE_MINIMIZED)
    {
      CRect rcClient(0, 0, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
      CRect rc = rcClient;

      rc.bottom = rc.top + rc.Height() / 2;

      rc.right = rc.left + rc.Width() / 2;
      m_header.MoveWindow(rc);

      rc.left = rc.right;
      rc.right = rc.left + rc.Height();
      m_btnCancel.MoveWindow(&rc);

      rc.left = rc.right + 5;
      rc.right = rcClient.right - rc.Height() - 5;
      m_editBox.MoveWindow(&rc);

      rc.left = rc.right + 5;
      rc.right = rcClient.right;
      m_btnOk.MoveWindow(&rc);

      rc = rcClient;
      rc.top += rc.Height() / 2;
      m_slider.MoveWindow(&rc);
      return bHandled = TRUE;
    }
    return bHandled = FALSE;
  }

  LRESULT OnIntChanged(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  {
    int val = m_slider.GetValue();
    TCHAR buf[32];
    ::_itot(val, buf, 10);
    m_editBox.SetWindowText(buf);
    return 0;
  }

  void OnEditChanged(UINT uNotifyCode, int nID, CWindow wndCtl)
  {
    CString txt;
    m_editBox.GetWindowText(txt);
    int val = ::_ttoi(txt);
    m_slider.SetValue(val);
  }

  LRESULT OnColorEdit(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  {
    if ((HWND)lParam == m_header.m_hWnd)
      return m_header.SendMessage(uMsg, wParam, lParam);
    return bHandled = FALSE;
  }

  LRESULT OnKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  {
    switch(wParam)
    {
    case VK_UP:
      m_slider.SendMessage(WM_KEYDOWN, VK_RIGHT);
      break;
    case VK_DOWN:
      m_slider.SendMessage(WM_KEYDOWN, VK_LEFT);
      break;
    }
    return 0;
  }

  void SetText(const CString& s)
  {
    m_text = s;
    if (m_editBox.m_hWnd)
    {
      m_editBox.SetWindowText(s);
      m_editBox.SetSel(s.GetLength(), -1);
    }
    if (m_slider.m_hWnd)
    {
      int val = ::_ttoi(s);
      m_slider.SetValue(val);
    }
  }

protected:
  CSkinnedText m_header;
  CSkinnedInt  m_slider;
};

class CListIntInputDlg : public CIntInputDlg
{
public:
  CListIntInputDlg(CListItem* pItem, const CRect& rcInner) : m_listItem(pItem), m_rcInner(rcInner)
  {}

  virtual void UpdateWindowPosition(bool redraw = true)
  {
    if (m_listItem)
    {
      CRect rc;
      rc = m_listItem->GetRect();
      rc.right = rc.left + m_rcInner.right;
      rc.left += m_rcInner.left;
      rc.bottom = rc.top + m_rcInner.bottom;
      rc.top += m_rcInner.top;
      MoveWindow(&rc, redraw);
    }
    else
    {
      CIntInputDlg::UpdateWindowPosition(redraw);
    }
  }

protected:
  CListItem* m_listItem;
  CRect m_rcInner;
};